﻿using System;
using System.Globalization;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Xml;
using System.Reflection;
using JigLibX.Physics;
using JigLibX.Collision;
using Services;
using Utilities.Menu.UIElements;
using TrenitaliaWP7.Resources;
using Services.Menu;
using Utilities;
using System.Windows;

namespace TrenitaliaWP7
{
    class ResultMenu : OrientableScreen
    {

        ArrayList<MyButton> froms, tos, time_froms, time_tos, changes, durations, label_changes, label_durations;
        ArrayList<MyButton> buttons;

        MyButton title;
        MyButton prevResult, nextResult;
        MyButton showAllDesc, showAllSwitch, showAllSwitch_help;
        public List<Result> results;
        InputManager input_manager;
        SpriteBatch spriteBatch;
        StateManager StateManager;
        //bool existsPopUp;
        SpriteFont font;
        Texture2D confirm, circle, WhitePixel, switchOn, switchOff, help;
        public int current_result;
        Rectangle dragArea;
        bool loading;
        public bool searchAllSolutions;
        public string originalQuery;
        public string originalBuyQuery;
        public bool prev_searchAllSolutions;
        public bool ClearOldData = false;
        //bool isWorking;
        //bool loadingAborted;
        public ResultMenu(Game game, Result result)
            : base(game)
        {
            results = new List<Result>();
            results.Add(result);
            current_result = 0;
            originalQuery = result.nextQuery;
            originalBuyQuery = result.buyQuery;
            result.nextQuery = GetNextQuery(result.nextQuery);
            
            InizializeObjects();
        }
        public ResultMenu(Game game)
            : base(game)
        {
            results = new List<Result>();
            current_result = 0;
            InizializeObjects();
        }
        public ResultMenu(Game game, List<Result> results)
            : base(game)
        {
            this.results = results;
            current_result = 0;
            InizializeObjects();
        }
        public void SetResult(Result result)
        {
            results.Clear();
            results.Add(result);
            current_result = 0;
            //result.nextQuery = GetNextQuery(result.nextQuery);
            originalQuery = result.nextQuery;
            originalBuyQuery = result.buyQuery;
            result.nextQuery = GetNextQuery(result.nextQuery);

        }
        void InizializeObjects()
        {
            froms = new ArrayList<MyButton>();
            tos = new ArrayList<MyButton>();
            time_froms = new ArrayList<MyButton>();
            time_tos = new ArrayList<MyButton>();
            changes = new ArrayList<MyButton>();
            durations = new ArrayList<MyButton>();
            buttons = new ArrayList<MyButton>();
            label_changes = new ArrayList<MyButton>();
            label_durations = new ArrayList<MyButton>();
            searchAllSolutions = false;
            prev_searchAllSolutions = searchAllSolutions;
        }
        public override void Initialize()
        {
            
            spriteBatch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
            StateManager = Game.Services.GetService(typeof(AStateManager)) as StateManager;
            //Game.Services.RemoveService(typeof(IInputManager));
            input_manager = new InputManager(Game);
            Game.Components.Add(input_manager);
            input_manager.OnTap += on_tap;
            //input_manager.OnHorizontalDrag += on_horizontal_drag;
            //input_manager.OnDragCompleted += on_drag_completed;
            input_manager.OnFlick += on_flick;
            //isWorking = false;
            //loadingAborted = false;
            loading = false;
            drag_start_point = Vector2.Zero;
            base.Initialize();
            if (current_result <= 0)
                prevResult.enabled = false;
        }
        protected override void LoadContent()
        {
            circle = Game.Content.Load<Texture2D>("circle");
            confirm = Game.Content.Load<Texture2D>("confirm");
            WhitePixel = Game.Content.Load<Texture2D>("WhitePixel");
            font = Game.Content.Load<SpriteFont>("Fonts/SegoeWP");
            switchOn = Game.Content.Load<Texture2D>("switch_on");
            switchOff = Game.Content.Load<Texture2D>("switch_off");
            help = Game.Content.Load<Texture2D>("credits");

            base.LoadContent();
        }
        public override void Update(GameTime gameTime)
        {
            input_manager.Enabled = this.Enabled;

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)// && !existsPopUp)
            {

                //Game.Components.Remove(input_manager);
                StateManager.SelectMainMenu2();
            } 
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();

            title.Draw(spriteBatch);

            for (int i = 0; i < buttons.Count; i++)
            {
                buttons[i].Draw(spriteBatch);
                froms[i].Draw(spriteBatch);
                tos[i].Draw(spriteBatch);
                time_froms[i].Draw(spriteBatch);
                time_tos[i].Draw(spriteBatch);
                changes[i].Draw(spriteBatch);
                durations[i].Draw(spriteBatch);
                label_durations[i].Draw(spriteBatch);
                label_changes[i].Draw(spriteBatch);
            }
            showAllSwitch.Draw(spriteBatch);
            showAllDesc.Draw(spriteBatch);
            showAllSwitch_help.Draw(spriteBatch);
            prevResult.Draw(spriteBatch);
            nextResult.Draw(spriteBatch);
            spriteBatch.End();
            base.Draw(gameTime);
        }
        
        void on_tap(Vector2 tap_position)
        {
            if (press_wait < PRESS_INTERVAL/* || existsPopUp*/ || loading) return;
            if (StateManager.isTrial)
            {
                if (RectContaintsVect(Game1.trial_rectangle, tap_position))
                {
                    OpenMarket(Game1.APP_ID);
                    return;
                }
            }
            if (prevResult.tapped_on(tap_position))
            {
                current_result--;
                ChangeOrientation();
                if (current_result <= 0)
                    prevResult.enabled = false;
                else
                    prevResult.enabled = true;
            }
            else if (nextResult.tapped_on(tap_position))
            {
                if (current_result < results.Count - 1)
                {
                    current_result++;
                    ChangeOrientation();
                }
                else if (!loading)
                    startHTMLRequest(results[current_result].nextQuery);
            }
            else if (showAllSwitch.tapped_on(tap_position) && !loading)
            {
                prev_searchAllSolutions = searchAllSolutions;
                searchAllSolutions = !searchAllSolutions;
                if (searchAllSolutions)
                    showAllSwitch.texture = switchOn;
                else
                    showAllSwitch.texture = switchOff;
                //Storage.SaveOptionsState(StateManager.OptionsState);
                current_result = 0;
                ClearOldData = true;
                startHTMLRequest(GetStartingQuery(originalQuery));
            }
            else if (showAllSwitch_help.tapped_on(tap_position) && !loading)
            {
                MessageBox.Show(Strings.AllSolutions_Help);
            }
            else
            {
                for (int i = 0; i < buttons.Count; i++)
                {
                    if (buttons[i].tapped_on(tap_position))
                    {
                        var index = 1 + (current_result * 5 + i);
                        results[current_result].solutions[i].buy_query = results[current_result].buyQuery
                            + (searchAllSolutions ? "&economy=1&det=" : "&economy=0&det=") + 
                            + index +
                            "&solotreno=0&noreservation=0&traintype=&car=0&dc=1";
                        StateManager.OpenDetailsMenu(results[current_result].solutions[i], false);
                    }
                }
            }
        }
        
        string GetNextQuery(string query){
            var economy = searchAllSolutions ? "&economy=1" : "";
            return query+economy+"&npag=" + (current_result+2);
        }
        string GetStartingQuery(string query)
        {
            var economy = searchAllSolutions ? "&economy=1" : "";
            return query + economy;
        }
        void startHTMLRequest(string query)
        {
            //loadingAborted = false;
            //isWorking = true;
            //StateManager.OpenLoadingComponent(this);
            StateManager.OpenLoadingComponent(this, AbortRefresh);
            loading = true;
            new Thread(new ThreadStart(() =>
            {
                Utilities.getHTML(query, GotHTML, ErrorGettingHTML);
            })).Start();
        }
        void AbortRefresh()
        {
            //loadingAborted = true;
            loading = false;
            this.Enabled = true;
            input_manager.Enabled = true;
            ChangeOrientation();
            if (prev_searchAllSolutions != searchAllSolutions)
            {
                searchAllSolutions = prev_searchAllSolutions;
                if (searchAllSolutions)
                    showAllSwitch.texture = switchOn;
                else
                    showAllSwitch.texture = switchOff;
            }
            ClearOldData = false;
        }
        //void ClosePopUp()
        //{
        //    existsPopUp = false;
        //    input_manager.Enabled = true;
        //    Game.Components.Add(input_manager);
        //    press_wait = 0;
        //}
        string GetBuyQuery()
        {
            var economy = searchAllSolutions ? "&economy=1&det=" : "&economy=0&det=";
            economy = "";
            if (results.Count > 0)
                return results[current_result].buyQuery+economy;
            else
                return originalBuyQuery + economy;
        }
        void GotHTML(string html)
        {
            if (!loading)
                return;
            StateManager.CloseLoadingComponent(this);
            //HTMLPaser parser = new HTMLPaser(html);

            if (ClearOldData)
            {
                results.Clear();
                ClearOldData = false;
                current_result = -1;
            }

            try
            {
                ResultParser parser = new ResultParser(html);
                var newResult = parser.getResult();
                //newResult.query = results[current_result].query;
                //if (results.Count > 0)
                //    newResult.buyQuery = results[current_result].buyQuery;
                //else
                    newResult.buyQuery = GetBuyQuery();

                current_result++;
                newResult.nextQuery = GetNextQuery(newResult.nextQuery);
                results.Add(newResult);
                //StateManager.SavedResults.Add(new SavedResults() { results = results });
                //Storage.SaveSavedResults(StateManager.SavedResults);
            }
            catch (Exception e)
            {
                e.ToString();
                MessageBox.Show(Strings.ErrorGettingData);
            }
            //current_result++;
            ChangeOrientation();
            loading = false;
            //isWorking = false;
        }

        void ErrorGettingHTML()
        {
            StateManager.CloseLoadingComponent(this);
            //StateManager.OpenErrorPopUp(ClosePopUp, Strings.ErrorGettingData, "", font, confirm, circle, WhitePixel, Color.Black);
            //input_manager.Enabled = false;
            //Game.Components.Remove(input_manager);
            //existsPopUp = true;
            ClearOldData = false;
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
            { StateManager.OpenNotifyPopUp(Strings.ErrorGettingData); });
            loading = false;
        }
        public override void SetPortraitOrientation()
        {

            var emptyTexture = Game.Content.Load<Texture2D>("emptyPixel");
            var box = Game.Content.Load<Texture2D>("bar_box");
            var titleFont = Game.Content.Load<SpriteFont>("Fonts/SegoeWP_Title");
            var smallFont = Game.Content.Load<SpriteFont>("Fonts/SegoeWP_Small");
            var back = Game.Content.Load<Texture2D>("back");
            var next = Game.Content.Load<Texture2D>("next");
            
            title = new MyButton(new Rectangle(20, 70, 200, 80), Strings.Result + "\n" + Strings.TouchOne, Color.White, titleFont, TextPos.Left);

            prevResult = new MyButton(new Rectangle(150, 730, 50, 50), back, Color.White, circle, Color.White);
            nextResult = new MyButton(new Rectangle(280, 730, 50, 50), next, Color.White, circle, Color.White);


            buttons.Clear();
            froms.Clear();
            tos.Clear();
            time_froms.Clear();
            time_tos.Clear();
            durations.Clear();
            changes.Clear();
            label_changes.Clear();
            label_durations.Clear();
            if (current_result < 0 || current_result >= results.Count)
                current_result = 0;
            var t= results[current_result].solutions;
            int buttons_height = 80;
            var initial_y = 150;
            for (int i = 0; i < t.Count; i++)
            {
                buttons.Add(new MyButton(new Rectangle(20, initial_y + (buttons_height + 10) * i, 440, buttons_height), box, Color.White));
                froms.Add(new MyButton(new Rectangle(44, initial_y + 15 + (buttons_height + 10) * i, 80, 20), t[i].from, Color.White, smallFont));
                tos.Add(new MyButton(new Rectangle(148, initial_y + 15 + (buttons_height + 10) * i, 80, 20), t[i].to, Color.White, smallFont));
                time_froms.Add(new MyButton(new Rectangle(44, initial_y + 45 + (buttons_height + 10) * i, 80, 20), t[i].departure, Color.White, smallFont));
                time_tos.Add(new MyButton(new Rectangle(148, initial_y + 45 + (buttons_height + 10) * i, 80, 20), t[i].arrival, Color.White, smallFont));
                label_durations.Add(new MyButton(new Rectangle(252, initial_y + 15 + (buttons_height + 10) * i, 80, 20), Strings.Duration, Color.White, smallFont));
                durations.Add(new MyButton(new Rectangle(252, initial_y + 45 + (buttons_height + 10) * i, 80, 20), t[i].duration, Color.White, smallFont));
                label_changes.Add(new MyButton(new Rectangle(356, initial_y + 15 + (buttons_height + 10) * i, 80, 20), Strings.Changes, Color.White, smallFont));
                changes.Add(new MyButton(new Rectangle(356, initial_y + 45 + (buttons_height + 10) * i, 80, 20), "" + t[i].changes.Count, Color.White, smallFont));
            }
            dragArea = new Rectangle(20, initial_y, 440, 200 + (buttons_height + 10) * 5);
            if (current_result <= 0)
                prevResult.enabled = false;
            flick_multiplier = 1;

            showAllDesc = new MyButton(new Rectangle(20, 650, 200, 60), Strings.AllSolutions, Color.White, font, TextPos.Left);
            showAllSwitch_help = new MyButton(new Rectangle(250, 650 - 10, 40, 40), help, Color.White, circle, Color.White);
            showAllSwitch = new MyButton(new Rectangle(350, 650 - 10, 100, 40), searchAllSolutions ? switchOn : switchOff, Color.White);

        }
        public override void SetLandScapeOrientation()
        {
            var emptyTexture = Game.Content.Load<Texture2D>("emptyPixel");

            var titleFont = Game.Content.Load<SpriteFont>("Fonts/SegoeWP_Title");
            var smallFont = Game.Content.Load<SpriteFont>("Fonts/SegoeWP_Small");
            var box = Game.Content.Load<Texture2D>("bar_box");
            var back = Game.Content.Load<Texture2D>("back");
            var next = Game.Content.Load<Texture2D>("next");
            title = new MyButton(new Rectangle(100, 20, 200, 60), Strings.Result + " - " + Strings.TouchOne, Color.White, titleFont, TextPos.Left);

            prevResult = new MyButton(new Rectangle(25, 150, 50, 50), back, Color.White, circle, Color.White);
            nextResult = new MyButton(new Rectangle(25, 280, 50, 50), next, Color.White, circle, Color.White);

            buttons.Clear();
            froms.Clear();
            tos.Clear();
            time_froms.Clear();
            time_tos.Clear();
            durations.Clear();
            changes.Clear();
            label_changes.Clear();
            label_durations.Clear();
            if (current_result < 0 || current_result >= results.Count)
                current_result = 0;
            var t = results[current_result].solutions;
            int buttons_height = 60;
            var initial_y = 60;
            for (int i = 0; i < t.Count; i++)
            {
                buttons.Add(new MyButton(new Rectangle(180, initial_y + (buttons_height + 10) * i, 600, buttons_height), box, Color.White));
                froms.Add(new MyButton(new Rectangle(204, initial_y + 5 + (buttons_height + 10) * i, 100, 20), t[i].from, Color.White, smallFont));
                tos.Add(new MyButton(new Rectangle(328, initial_y + 5 + (buttons_height + 10) * i, 100, 20), t[i].to, Color.White, smallFont));
                time_froms.Add(new MyButton(new Rectangle(204, initial_y + 35 + (buttons_height + 10) * i, 100, 20), t[i].departure, Color.White, smallFont));
                time_tos.Add(new MyButton(new Rectangle(328, initial_y + 35 + (buttons_height + 10) * i, 100, 20), t[i].arrival, Color.White, smallFont));
                label_durations.Add(new MyButton(new Rectangle(452, initial_y + 5 + (buttons_height + 10) * i, 100, 20), Strings.Duration, Color.White, smallFont));
                durations.Add(new MyButton(new Rectangle(452, initial_y + 35 + (buttons_height + 10) * i, 100, 20), t[i].duration, Color.White, smallFont));
                label_changes.Add(new MyButton(new Rectangle(576, initial_y + 5 + (buttons_height + 10) * i, 100, 20), Strings.Changes, Color.White, smallFont));
                changes.Add(new MyButton(new Rectangle(576, initial_y + 35 + (buttons_height + 10) * i, 100, 20), "" + t[i].changes.Count, Color.White, smallFont));
            }
            dragArea = new Rectangle(150, initial_y, 600, 120 + (buttons_height + 10) * 5);
            if (current_result <= 0)
                prevResult.enabled = false;
            flick_multiplier = 1;
            //if (prev_orientation == DisplayOrientation.LandscapeLeft)
            //    flick_multiplier = -1;

            showAllDesc = new MyButton(new Rectangle(175, 440, 200, 60), Strings.AllSolutions, Color.White, font, TextPos.Left);
            showAllSwitch_help = new MyButton(new Rectangle(500, 440 - 10, 40, 40), help, Color.White, circle, Color.White);
            showAllSwitch = new MyButton(new Rectangle(675, 440 - 10, 100, 40), searchAllSolutions ? switchOn : switchOff, Color.White);

        }

        Vector2 drag_start_point = Vector2.Zero;
        float flick_multiplier;
        void on_horizontal_drag(Vector2 drag_pos)
        {
            if (drag_start_point != Vector2.Zero && !loading)
            {
                var distance = Vector2.Distance(drag_start_point, drag_pos);
                if (distance > 30)
                {
                    if (drag_pos.X > drag_start_point.X)
                    {
                        if (current_result > 0)
                        {
                            current_result--;
                            ChangeOrientation();
                            if (current_result <= 0)
                                prevResult.enabled = false;
                            else
                                prevResult.enabled = true;
                        }
                    }
                    else
                    {
                        if (current_result < results.Count - 1)
                        {
                            current_result++;
                            ChangeOrientation();
                        }
                        else
                        {
                            startHTMLRequest(results[current_result].nextQuery);

                        }
                    }

                }
                
            }
            drag_start_point = drag_pos;
        }
        void on_drag_completed()
        {
            drag_start_point = Vector2.Zero;

        }
        void on_flick(Vector2 delta)
        {
            if (Math.Abs(delta.X) > 30)
            {
                if (delta.X * flick_multiplier > 0)
                {
                    if (current_result > 0)
                    {
                        current_result--;
                        ChangeOrientation();
                        if (current_result <= 0)
                            prevResult.enabled = false;
                        else
                            prevResult.enabled = true;
                    }
                }
                else
                {
                    if (current_result < results.Count - 1)
                    {
                        current_result++;
                        ChangeOrientation();
                    }
                    else if(!loading)
                    {
                        startHTMLRequest(results[current_result].nextQuery);

                    }
                }
            }
        }
    }
}
